package com.amkai.aes.webservice.binary.objecthandler.casehistory;
//veghar AES-5502
import java.io.IOException;
import java.io.Serializable;
import java.io.StringBufferInputStream;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.TimeZone;
import java.util.Vector;

import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableModel;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.hibernate.Query;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

import com.amkai.aes.aescommon.service.binary.job.casehistory.ImportCDMJob;
import com.amkai.aes.aescommon.service.result.casehistory.ImportCDMResult;
import com.amkai.aes.generatedbeans.acimport.ImportCdm;
import com.amkai.aes.generatedbeans.organization.Department;
import com.amkai.aes.webservice.binary.JobObjectHandler;
import com.amkai.common.extensions.hibernate.config.SiteManager;
import com.amkai.common.extensions.hibernate.config.manager.SessionManager;


public class ImportCDMHandler  implements  JobObjectHandler<ImportCDMJob, Serializable, ImportCDMResult> {
	private static final Log log = LogFactory.getLog(ImportCDMHandler.class);
	// KKORNEL: AES-15247
	private long offset = 0;
	
	@SuppressWarnings("unchecked")
	@Override
	public ImportCDMResult process(ImportCDMJob job, Serializable object)
	throws Exception {
		// TODO Auto-generated method stub
		ImportCDMResult result = new ImportCDMResult();
		SessionManager sm = SiteManager.Start();
		try {
			sm.openSession();
			// KKORNEL: AES-15247
			Department department = sm.get(Department.class, job.getModuleDepartment().getId());
			boolean hasACTimeZone = department.getAcTimeZone() != null;
			TimeZone timeZoneToUse = null; 
			TimeZone deparmentTimeZone = TimeZone.getTimeZone(department.getTimeZone());
			if (hasACTimeZone) {
				timeZoneToUse = TimeZone.getTimeZone(department.getAcTimeZone());
			} else {
				timeZoneToUse = deparmentTimeZone;
			}
			offset = TimeZone.getDefault().getRawOffset() - timeZoneToUse.getRawOffset();
			if (hasACTimeZone && (!TimeZone.getDefault().getID().equals(deparmentTimeZone.getID()))) {
				offset += deparmentTimeZone.getRawOffset() - TimeZone.getDefault().getRawOffset();
			}
//			sm.openTransaction();

			Query q = sm.execute("from ImportCdm cdm where cdm.pmCase.id = :caseid");
			q = q.setLong("caseid", job.caseID);
			List<ImportCdm> iCDM = q.list();
			for (ImportCdm aimportCdm : iCDM) {
				String aXML = aimportCdm.getXml();
				result.CDMResult.put(aimportCdm.getTitle(), processXML(aXML));
			}
//		} catch (Exception e) {
			//logger.error("ImportCheckoutHandler: ", e);
//			sm.rollbackTransaction();
//			throw e;
		} finally {
			sm.closeSession();
		}
		return result;
	}
	public TableModel processXML (String aXML){

		final String DATE_TIME_INPUT_MASK = "yyyy-MM-dd'T'HH:mm:ss.SSS";
		final String DATE_TIME_OUTPUT_MASK = "yyyy-MM-dd HH:mm:ss";  
		final SimpleDateFormat SDF_IN = new SimpleDateFormat(DATE_TIME_INPUT_MASK);
		final SimpleDateFormat SDF_OUT = new SimpleDateFormat(DATE_TIME_OUTPUT_MASK);
		Vector <Vector<Object>> tableArray = new Vector<Vector<Object>>();
		Vector <String> colNameList = new Vector<String>();
		DocumentBuilderFactory docBuilderFactory = DocumentBuilderFactory.newInstance();
		DocumentBuilder docBuilder = null;
		TableModel result = null;
		//return null;
		try {
			docBuilder = docBuilderFactory.newDocumentBuilder();
		} catch (ParserConfigurationException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}
		try {
			Document doc;
			try {
				StringBufferInputStream strBuff = new StringBufferInputStream(aXML);
				doc = docBuilder.parse(strBuff);
				doc.getDocumentElement ().normalize ();
				NodeList columnames = doc.getElementsByTagName("Column");
				int cl = columnames.getLength();
				Vector<Object> tblRow = new Vector<Object>();
				tblRow.setSize(cl);

				List <Integer> inVisibleColumns = new ArrayList <Integer>();
				for (int i = 0; i < cl; i++) {
					Node colum = columnames.item(i);
					Element ecolum = (Element)colum;

					NodeList captions  = ecolum.getElementsByTagName("Caption");

					NodeList colVisible = ecolum.getElementsByTagName("Visible");

					if (colVisible.item(0) != null) {
						colNameList.add(captions.item(0).getTextContent());
						tblRow.add(i, (String)"");
					}else 
					{

						inVisibleColumns.add(i);
					}
				}

				NodeList tvalues = doc.getElementsByTagName("Object");
				int l = tvalues.getLength();
				for (int i = 0; i < l; i++) {
					//tmptblRow.clear();
					Vector<Object> tmptblRow = new Vector<Object>();
					for (int j = 0; j < tblRow.size(); j++) {
						tmptblRow.add(j, tblRow.elementAt(j));
					}
					tableArray.add(tmptblRow);
					Node row = tvalues.item(i);
					Element erow = (Element)row;
					NodeList cols  = erow.getElementsByTagName("Item");
					for (int j=0; j < cols.getLength(); j++){

						Node col = cols.item(j);
						NamedNodeMap nnp = col.getAttributes();

						Object v = null;
						Node colId = nnp.getNamedItem("ColumnId");

						Integer icolId = Integer.parseInt(colId.getTextContent());

						if (inVisibleColumns.indexOf(icolId) == -1) { 
							Node dtNode = nnp.getNamedItem("dt:dt");

							Type tp = dtNode==null?Type.PLAIN:Type.fromStr(dtNode.getTextContent());
							try {
								switch (tp) {
								case DATETIME:
									Date date = (Date) SDF_IN.parse(col.getTextContent());
									// KKORNEL: AES-15247
									if (date != null) {
										Calendar calendar = Calendar.getInstance();
										calendar.setTimeInMillis(date.getTime() + offset);
										String formattedDate = SDF_OUT.format(calendar.getTime());
										v = formattedDate;
									} else {
										v = "N/A";
									}
									log.debug(col.getTextContent());
									break;
								case BOOLEAN:
									if (col != null){
										if (col.getTextContent().equals("0") ){
											v = "False";
										}else
											v = "True";
										break;
									}	
								default:
									v = col.getTextContent();
								break;
								}
								tmptblRow.setElementAt(v, icolId);

							} catch (Exception e) {
								e.printStackTrace();
							}
						}
					}
					for (int k = tmptblRow.size()-1; k>-1 ; k--) {	
						if (tmptblRow.get(k) == null) {
							tmptblRow.remove(k);
						}

					}

				}
				result = new DefaultTableModel(tableArray, colNameList);


			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}


		} catch (SAXException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();

		}

		return result;
	}

	enum Type {
		DATETIME,
		BOOLEAN,
		INT,
		PLAIN
		;
		static Type fromStr(String s) {
			return valueOf(s.toUpperCase());
		}
	}

}
